"""
仿射模型
本例用简单的仿射模型进行数据推理
f(x)=x*w
loss=(f(xn)-y)**2
"""

import numpy as np
import matplotlib.pyplot as plt

# 定义已知的数据集,training的dataset
x_data = [1.0, 2.0, 3.0]
y_data = [2.0, 4.0, 6.0]


def forward(x, w):
    """
    前馈函数,f(x)=w*x
    :param x: 输入的x值
    :param w: 权重,在这里是仿射模型的斜率
    :return: 获得的y值
    """
    return x * w


def loss(x, y, w):
    """
    单样本的损失函数
    :param x: 当前的x值
    :param y: x对应的,在dataset中的y值
    :param w: 权重,在这里是仿射模型的斜率
    :return: 当前x值的损失函数
    """
    # 获得当前x计算的前馈值,即使用猜测的w权重计算出来的y_hat值
    y_hat = forward(x, w)
    # 损失函数定义为y_hat-y的平方,即使用当前w权重得到的y值,和数据集中的真实值作差
    return pow(y_hat - y, 2)


# w权重记录表
w_list = []
# mean square error 平均平方误差,为每次w猜测权重后,对每个样本进行loss损失函数计算的均值
mse_list = []

# 设定猜测的w权重,从0到4.1,步进0.1
for w in np.arange(0, 4.1, 0.1):
    # 每个权重下的mse平均平方误差
    w_sam = 0.0
    # 遍历数据集,计算当前权重下的mse平均平方误差
    for x, y in zip(x_data, y_data):
        # 计算损失值
        theLoss = loss(x, y, w)
        # 求和
        w_sam += theLoss
    # 求取mse
    theMse = w_sam / len(x_data)
    # 记录当前的权重和mse平均平方误差
    w_list.append(w)
    mse_list.append(theMse)

# 根据当前的权重表和平均平方误差绘图
plt.plot(w_list, mse_list)
# y轴是损失曲线
plt.ylabel("loss")
# x轴是权重
plt.xlabel("w")

plt.show()
